﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1
{
	class Form1
	{
		Form1()
		{
			// In this example, initialize the Mesh object
			// with 4 tessellations
			this.InitializeMesh(4);
		}

		private void InitializeMesh(int tessellation)
		{
			Mesh mesh1 = CreateHeightfieldMesh(tessellation);

		}
		private float GetHeight(float x, float y)
		{
			return 0;
			//TODO: fill in this function
		}

		private Mesh CreateHeightfieldMesh(int tessellation)
		{
			Mesh mesh;

			Device device = null; // TODO: initialize this

			short[] arrayIndices = new short[(tessellation - 1) * (tessellation - 1) * 6];
			CustomVertex.PositionTextured[] arrayVertices =	new CustomVertex.PositionTextured[tessellation * tessellation];
			AttributeRange attributeRange = new AttributeRange();

			// Create mesh with desired vertex format and desired size
			mesh = new Mesh(arrayIndices.Length / 3, arrayVertices.Length, MeshFlags.SystemMemory,
			CustomVertex.PositionTextured.Format, device);

			// For each point in the height field calculate the x, y, z and
			// texture coordinates.
			for (int y = 0; y < tessellation; y++)
			{
				for (int x = 0; x < tessellation; x++)
				{
					int arrayIndex = y * tessellation + x;
					float xCoordinate = (float)x / (float)(tessellation - 1);
					float yCoordinate = (float)y / (float)(tessellation - 1);
					CustomVertex.PositionTextured vertex = new CustomVertex.PositionTextured
							(xCoordinate, yCoordinate, GetHeight(xCoordinate, yCoordinate), xCoordinate, yCoordinate);
					arrayVertices[arrayIndex] = vertex;
				}
			}

			// Calculate the index buffer.
			for (int y = 0; y < (tessellation - 1); y++)
			{
				for (int x = 0; x < (tessellation - 1); x++)
				{
					int arrayIndex = (y * (tessellation - 1) + x) * 6;
					int vertexIndex = y * tessellation + x;

					arrayIndices[arrayIndex] = (short)vertexIndex;
					arrayIndices[arrayIndex + 1] = (short)(vertexIndex + 1);
					arrayIndices[arrayIndex + 2] = (short)(vertexIndex + tessellation);
					arrayIndices[arrayIndex + 3] = (short)(vertexIndex + tessellation);
					arrayIndices[arrayIndex + 4] = (short)(vertexIndex + 1);
					arrayIndices[arrayIndex + 5] = (short)(vertexIndex + tessellation + 1);
				}
			}

			// There is only one attribute value for this mesh.
			// By specifying an attribute range the DrawSubset function
			// does not have to scan the entire mesh for all faces that are
			// are marked with a particular attribute id.
			attributeRange.AttributeId = 0;
			attributeRange.FaceStart = 0;
			attributeRange.FaceCount = arrayIndices.Length / 3;
			attributeRange.VertexStart = 0;
			attributeRange.VertexCount = arrayVertices.Length;

			mesh.VertexBuffer.SetData(arrayVertices, 0, LockFlags.None);
			mesh.IndexBuffer.SetData(arrayIndices, 0, LockFlags.None);
			mesh.SetAttributeTable(new AttributeRange[] { attributeRange });

			return (mesh);

		}
		public static void Main()
		{
			try
			{
				Form Form1 = new Form();
				Application.Run(Form1);
			}
			catch (NotSupportedException)
			{
				MessageBox.Show("Your device does not have the needed 3d " +
					"support to run this sample");
			}
			catch (DriverUnsupportedException)
			{
				MessageBox.Show("Your device does not have the needed 3d " +
					"driver support to run this sample");
			}
			catch (Exception e)
			{
				MessageBox.Show("The sample has run into an error and " +
					"needs to close: " + e.Message);
			}
		}
	}
}
